package cn.xxm.strategy.pay.validate.processor;


import cn.xxm.strategy.pay.i18n.response.ResponseInfo;
import cn.xxm.strategy.pay.validate.annotation.VEmpty;
import cn.xxm.strategy.pay.validate.annotation.VNotEmpty;
import cn.xxm.strategy.pay.validate.exception.ValidateException;
import org.springframework.cglib.reflect.FastClass;
import org.springframework.cglib.reflect.FastMethod;

import java.lang.reflect.Array;


@SuppressWarnings("rawtypes")
public class EmptyProcessor extends ValidateProcessor {
	private boolean notEmpty = true;
	private boolean blankStringIsEmpty = true;//空白字符串是否视为空字符串
	private FastMethod emptyMethod = null;
	private Class<?> valueType;

	@SuppressWarnings("unchecked")
	public EmptyProcessor(VEmpty vEmpty){
		Class<Enum> enumClass = (Class<Enum>)vEmpty.enumClass();
		Enum enumInstance = Enum.valueOf(enumClass, vEmpty.enumName());
		if(! (enumInstance instanceof ResponseInfo)) {//枚举类型没实现ResponseInfo则抛异常
			throw new ValidateException("枚举类型<"+enumClass+">未实现接口<"+ResponseInfo.class+">")  ;
		}
		super.setResponseInfo(enumInstance);
		this.notEmpty = false;
		this.blankStringIsEmpty = vEmpty.blankStringIsEmpty();
	}
	
	@SuppressWarnings("unchecked")
	public EmptyProcessor(VNotEmpty vNotEmpty){
		Class<Enum> enumClass = (Class<Enum>)vNotEmpty.enumClass();
		Enum enumInstance = Enum.valueOf(enumClass, vNotEmpty.enumName());
		if(! (enumInstance instanceof ResponseInfo)) {//枚举类型没实现ResponseInfo则抛异常
			throw new ValidateException("枚举类型<"+enumClass+">未实现接口<"+ResponseInfo.class+">")  ;
		}
		super.setResponseInfo(enumInstance);
		this.notEmpty = true;
		this.blankStringIsEmpty = vNotEmpty.blankStringIsEmpty();
	}
	
	@Override
	public boolean validate(Object value){
		return notEmpty ^ validateEmpty(value);
	}
	
	public boolean validateEmpty(Object value){
		if(value == null){
			return true;
		}
		if(valueType == null){
			valueType = value.getClass();
		}
		if(valueType.isArray()){
			return Array.getLength(value) == 0;
		}
		if(valueType == String.class && blankStringIsEmpty){//空白字符串是否视为空字符串
			String str = (String) value;
			for (int i = 0; i < str.length(); i++) {
				if(!Character.isWhitespace(str.charAt(i))){
					return false;
				}
			}
			return true;
		}
		boolean isEmpty = false;
		try {
			if(emptyMethod == null){
				emptyMethod = FastClass.create(valueType).getMethod("isEmpty", null);
			}
			isEmpty = ((Boolean)emptyMethod.invoke(value, null)).booleanValue();
		} catch (Exception e) {
			logger.info("isEmpty method invoke fail:{}",e);
		}
		return isEmpty;
	}

	public boolean isNotEmpty(){
		return notEmpty;
	}
	
	public void setNotEmpty(boolean notEmpty){
		this.notEmpty = notEmpty;
	}
	
	public boolean isRequiredEmpty(){
		return !notEmpty;
	}
	
	public void setRequiredEmpty(boolean requiredEmpty){
		notEmpty = !requiredEmpty;
	}
}
